package dst.ass1.jpa.listener;

import java.util.Date;


/**
 * 1.4.c.
 * simple default listener
 * listener should record the number of entities loaded, updated and removed. This listener also records how often a persist 
 * operation was successfully called and how much time all store-operations took in total
 * 
 * !!!Must be thread-safe!!!
 * realised with gate 
 * Because of different uses of variables and calculations AtomicInteger alone would not be safe
 *
 */
public class DefaultListener {

	private static int activePersistCount;
	private static Date persistStart;
	private static long overallPersistTime;

	private static final Object gate = new Object();  //gate to ensure thread safety

	private static int sumUpPersist;  //all Persists
	private static int sumUpLoad;
	private static int sumUpUpdate;
	private static int sumUpRemove;

	public void onPrePersist(Object object) {
		synchronized (gate) {
			activePersistCount++;
			if (activePersistCount == 1) {  //set new Date if new persist session started
				persistStart = new Date();
			}
		}
	}

	public void onPostPersist(Object object) {
		synchronized (gate) {
			sumUpPersist++;  //one persist more done

			activePersistCount--;
			if (activePersistCount == 0) {  //if there are no open active Persits -> sumUp the Time
				long seconds = new Date().getTime() - persistStart.getTime();  //calculate difference
				overallPersistTime += seconds;  //sumUp new difference
			}
		}
	}

	public void onPostUpdate(Object object) {
		synchronized (gate) {
			sumUpUpdate++;
		}
	}

	public void onPostLoad(Object object) {
		synchronized (gate) {
			sumUpLoad++;
		}
	}

	public void onPostRemove(Object object) {
		synchronized (gate) {
			sumUpRemove++;
		}
	}

	public static int getLoadOperations() {
		return sumUpLoad;
	}

	public static int getUpdateOperations() {
		return sumUpUpdate;
	}

	public static int getRemoveOperations() {
		return sumUpRemove;
	}

	public static int getPersistOperations() {
		return sumUpPersist;
	}

	public static long getOverallTimeToPersist() {
		return overallPersistTime;
	}

	public static double getAverageTimeToPersist() {
		synchronized (gate) {
			return (double) overallPersistTime / sumUpPersist;
		}
	}

	public static void clear() {
		synchronized (gate) {
			activePersistCount = 0;
			overallPersistTime = 0;
			persistStart = null;
			sumUpPersist = 0;
			sumUpLoad = 0;
			sumUpUpdate = 0;
			sumUpRemove = 0;
		}
	}

}
